package com.irishud.hudnavi;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.util.Log;

import com.hud.base.protocol.Endpoint;
import com.hud.base.protocol.EndpointEventHandler;
import com.hud.base.protocol.ProtoFilter;
import com.hud.base.tcp.TcpClientSocketThread;
import com.irishud.protocol.ProtoMsg;

import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;


public class CommService extends Service implements Endpoint {
    String TAG = "CommService";
    private WifiManager wifiManager;
    private long lastWifiScanTime;
    private Timer heartbeatTimer;
    private TcpClientSocketThread tcpClientSocketThread;

    @Override
    public void onCreate() {
        super.onCreate();

        EventBus.getDefault().register(this);
        wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);

        new Thread(new Runnable() {
            @Override
            public void run() {
                connectToWifiAp(wifiManager,"wifi_test","11111111",null);
            }
        }).start();
        // 设备心跳
        heartbeatTimer =new Timer();
        heartbeatTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                ProtoMsg protoMsg = new ProtoMsg("device.heartbeat","");
                if(tcpClientSocketThread!=null){
                    tcpClientSocketThread.send(protoMsg.toBytes());
                    //Log.w(TAG,"============> Device heart beat alive!(Client Mode)");
                }
            }
        },1000,1*1000);// 每隔3s发送一次心跳

        lastWifiScanTime = System.currentTimeMillis();
        final ProtoFilter protoFilter = new ProtoFilter();
        protoFilter.setLisenter(new ProtoFilter.OnFilterResultListener() {
            @Override
            public void OnMessageReceive(ByteBuffer bb) {
                //TODO parse ProtoMsage byte[]
                // 解析消息
                System.out.println("====> head:" +bb.getShort());
                System.out.println("---- total_len:" +bb.getInt());
                System.out.println("---- msg_type:" +bb.getInt());
                System.out.println("---- msg_id:" +bb.getLong());

                int action_len = bb.getInt();
                System.out.println("---- action_len:" +action_len);
                byte[] str_byte= new byte[action_len];
                bb.get(str_byte, 0, action_len);
                String action_string = new String(str_byte);
                System.out.println("action string:"+new String(str_byte));

                int data_len = bb.getInt();
                System.out.println("---- data_len:" +data_len);
                byte[] data_byte= new byte[data_len];
                bb.get(data_byte, 0, data_len);
                System.out.println("data string:"+new String(data_byte));

                ProtocolMessageDispatcher.getInstance().handleProtoMsg(CommService.this,action_string,data_byte);
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                tcpClientSocketThread = new TcpClientSocketThread("192.168.43.1",50002);
                tcpClientSocketThread.setReceiveListener(new TcpClientSocketThread.ReceiveListener() {
                    @Override
                    public void OnDataReceive(byte[] data, int len) {
                        protoFilter.onDataFiltering(data,len); // 添加到协议过滤
                    }
                });
                tcpClientSocketThread.setStateListener(new TcpClientSocketThread.TcpClientStateListener() {
                    @Override
                    public void onTcpClientReconnect(TcpClientSocketThread socketThread,String ip, int port) {
                        Log.e(TAG,"tcp client try to reconncet...");
                        if(!wifiManager.isWifiEnabled()){
                            Log.i(TAG,"========== open wifi==============>");
                            wifiManager.setWifiEnabled(true); // 重连时候尝试打开wifi，因为有时候wifi是关闭的!
                        }

                        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                        Log.i(TAG,"CURRENT ----> WIFI CONNECT INFO:"+wifiInfo.toString());
                        if(wifiInfo.getBSSID()==null || wifiInfo.getBSSID().equals("00:00:00:00:00:00") || wifiInfo.getSSID().contains("unknown")){
                            Log.i(TAG," lost wifi connection! ");
                            long now = System.currentTimeMillis();
                            long delta = now - lastWifiScanTime;
                            connectToWifiAp(wifiManager,"wifi_test","11111111",null);
                            if(delta > 15*1000){
                                wifiManager.startScan();
                                Log.e(TAG,"start wifi scanning...");
                                lastWifiScanTime = System.currentTimeMillis();
                            }
                        }
                    }
                    @Override
                    public void onTcpClientConnectionOk(TcpClientSocketThread socketThread, String serverIp, InetAddress ownIp, int port) {
                        Log.e(TAG,":allocate-----> 分配的IP地址："+ownIp.getHostAddress());
                    }

                    @Override
                    public void onTcpClientFailedConnection(TcpClientSocketThread socketThread,String ip, int port) {
                    }
                });
                tcpClientSocketThread.connect();
            }
        }).start();
    }

    @Subscribe
    public void handleCanBusEvent(CanBusEvent event){
    }

    private void handleProtoMsg(String action_string, byte[] data_byte) {
    }

    private WifiConfiguration wifiConfig(String netName, String netPwd) {
        WifiConfiguration wifiCong = new WifiConfiguration();
        wifiCong.SSID = "\"" + netName + "\"";// \"转义字符，代表"
        wifiCong.preSharedKey = "\"" + netPwd + "\"";// WPA-PSK密码
        wifiCong.hiddenSSID = false;
        wifiCong.status = WifiConfiguration.Status.ENABLED;
        return wifiCong;
    }

    private WifiConfiguration isExsits(String SSID) {
        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
        if(existingConfigs!=null && existingConfigs.size() > 0){
            for (WifiConfiguration existingConfig : existingConfigs) {
                if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                    return existingConfig;
                }
            }
        }
        return null;
    }

    private void connectToWifiAp(WifiManager mWifiManager,
                                 String netName,
                                 String netPwd,
                                 NaviFloatWindowService.WifiConnectionStateCallback callback) {
        if(!mWifiManager.isWifiEnabled()){
            Log.i(TAG,"WIFI 处于关闭状态，正打开wifi");
            mWifiManager.setWifiEnabled(true);
        }
        //配置Wifi信息
        WifiConfiguration wifiCong = wifiConfig(netName, netPwd);
        WifiConfiguration tempConfig = isExsits(netName);
        if (tempConfig != null) {
            wifiManager.removeNetwork(tempConfig.networkId);
        }

        // 将配置好的特定WIFI密码信息添加,添加完成后默认是不激活状态，成功返回ID，否则为-1
        int network = mWifiManager.addNetwork(wifiCong);
        Log.e(TAG, "network="+network);
        if (network != -1) {
            boolean connectWifiok = wifiManager.enableNetwork(network, true);
            if (connectWifiok) {
                Log.w(TAG,"wifi 连接成功！");
                if(callback!=null){
                    callback.onWifiConnected();
                }
            } else {
                Log.w(TAG,"wifi 连接失败！");
            }
        } else {
            Log.w(TAG,"wifi 网络连接错误 errocode:-1");
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void send(ByteBuffer byteBuffer) {
        tcpClientSocketThread.send(byteBuffer);
    }

    @Override
    public boolean isAvailable() {
        return tcpClientSocketThread.isConnected();
    }

    @Override
    public void destroy() {
    }

    @Override
    public void registerEndpointEventHandler(EndpointEventHandler endpointEventHandler) {
    }

    @Override
    public void unregisterEndpointEventHandler(EndpointEventHandler endpointEventHandler) {
    }
}
